﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace lan_file_transfer
{
    public abstract class Truck : I_Truck
    {
        public event Action<string> LOG_EVENT;
        /// <summary>
        /// 子类收到数据，传到Truck中处理
        /// </summary>
        internal Action<byte[]> RCV_ACTION;
        internal Queue<Task> taskQueue;
        internal Queue<DataPiece> sendDataPiecesQueue;
        internal Flags flags;
        /// <summary>
        /// 定义每次发送的数据内容大小
        /// </summary>
        internal int sendDataLength = 1024;
        public Truck()
        {
            init();
        }

        public abstract bool connect(int threadNum = 1);

        public virtual void Dispose()
        {

        }

        public void startSendFile(string path)
        {
            taskQueue.Enqueue(Task.Run(() =>
            {
                if(!File.Exists(path))
                {
                    log("file not exists");
                    return;
                }
                FileStream fs = new FileStream(path,FileMode.Open);
                sendDataPiecesQueue.Clear();
                int readFileLength = 0;
                flags.transFileToPieces_flag = true;
                while (flags.transFileToPieces_flag)
                {
                    if(sendDataPiecesQueue.Count<20480)
                    {
                        byte[] onceReadData = new byte[sendDataLength];
                        if ((readFileLength = fs.Read(onceReadData, 0, sendDataLength)) >0)
                        {
                            DataPiece onePiece = new DataPiece();
                            onePiece.Data = onceReadData;
                            sendDataPiecesQueue.Enqueue(onePiece);
                        }
                    }
                    else
                    {
                        Thread.Sleep(100);
                    }
                }
            }));
            taskQueue.Enqueue(Task.Run(() =>{
                object multiThreadLocker = new object();

            }));
        }
        private void singleSendFunction(DataPiece piece,ref object locker)
        {

        }

        public void startRcvFile(string path)
        {
        }

        public void stopRcvFile()
        {
            throw new NotImplementedException();
        }

        #region 子类需要实现的实际收发与连接的函数
        protected abstract void send(byte[] data, int index);
        protected abstract void rcv();
        protected virtual void init()
        {
            taskQueue = new Queue<Task>();
            sendDataPiecesQueue = new Queue<DataPiece>();

            flags = new Flags();
            flags.L1 = 0;
            flags.L2 = 0;
        }

        #endregion
        protected void log(string str)
        {
            str = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss-fff:")+str;
            LOG_EVENT?.Invoke(str);
        }
    }
}
